/**
 * Alipay.com Inc.
 * Copyright (c) 2004-2018 All Rights Reserved.
 */
package com.zxh.blog.util.excel;

import org.apache.commons.beanutils.ConvertUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * excel数据
 * @author tangping.tp
 * @version $Id: ExcelData.java, v 0.1 2018年09月06日 下午1:06 tangping.tp Exp $
 */
public class ExcelData<T> {

  /**
   * 列头
   */
  private List<String> headerRow;

  /**
   * excel对应的类对象的列配置
   */
  private ExcelColumnsConfigMap excelColumnsConfigMap;

  /**
   * 数据
   */
  private List<T> dataList = new ArrayList<T>();

  /**
   * 用于读取excel的构造器
   * 初始化表头和列配置
   * @param headerRow
   * @param tClass
   */
  ExcelData(List<String> headerRow, Class<T> tClass) {
    this.headerRow = headerRow;
    excelColumnsConfigMap = ExcelColumnsConfigMap.parse(tClass);
  }

  /**
   * 用于写excel的构造器
   * 初始化列配置信息
   * @param tClass
   */
  ExcelData(Class<T> tClass, List<T> dataList) {
    excelColumnsConfigMap = ExcelColumnsConfigMap.parse(tClass);
    this.headerRow = excelColumnsConfigMap.getHeaderName();
    this.dataList = dataList;
  }

  /**
   * 添加一行数据
   * @param dataRowCellValues
   * @param tClass
   */
  void addData(List<String> dataRowCellValues, Class<T> tClass, int rowNum) throws InstantiationException, IllegalAccessException {
    T data = this.parseRow(dataRowCellValues, tClass, rowNum);
    dataList.add(data);
  }

  /**
   * 获取excel String数据
   * @return
   */
  List<List<String>> getRows(Class<T> tClass) {
    List<List<String>> rows = new ArrayList<List<String>>();
    dataList.forEach(e -> rows.add(getRow(tClass, e)));
    return rows;
  }

  /**
   * 获取一行的数据
   * @param tClass
   * @param data
   * @return
   */
  private List<String> getRow(Class<T> tClass, T data) {
    List<String> row = new ArrayList<>();
    headerRow.forEach(e -> {

      Optional<ExcelColumnConfigModel> fieldName = excelColumnsConfigMap.getConfig(e);
      Optional<Field> fieldOpt = ReflectUtils.getField(tClass, fieldName.get().getName());

      Field field = fieldOpt.get();
      field.setAccessible(true);
      String valueStr = "";
      try {
        Object value = field.get(data);
        if (null != value) {
          valueStr = ConvertUtils.convert(value);
        }
      } catch (IllegalAccessException e1) {
      }
      row.add(valueStr);
    });
    return row;
  }

  /**
   * 解析数据
   * @param dataRowCellValues
   * @param tClass
   * @return
   */
  private T parseRow(List<String> dataRowCellValues, Class<T> tClass, int rowNum) throws IllegalAccessException, InstantiationException {

    T dataObject = tClass.newInstance();
    for (int i = 0; i < dataRowCellValues.size(); i++) {
      Optional<ExcelColumnConfigModel> configResult = this.excelColumnsConfigMap.getConfig(headerRow.get(i));

      ExcelColumnConfigModel config = configResult.get();
      String fieldStringValue = dataRowCellValues.get(i);
      //检查2（插入检查）：如果导入操作不是更新操作（而是插入操作），则需要检查要求不能为空的字段是否确实不为空
      if (!config.canEmpty()) {
      }

      String fieldName = config.getName();
      Optional<Field> fieldOpt = ReflectUtils.getField(tClass, fieldName);

      Field field = fieldOpt.get();
      field.setAccessible(true);
      Class<?> fieldType = field.getType();

      Object fieldRealTypeValue = null;
      if (fieldStringValue != null) {
        fieldRealTypeValue = StringConvertUtils.convert(fieldStringValue, fieldType);
      }
      //此次注意类型异常
      field.set(dataObject, fieldRealTypeValue);
    }
    return dataObject;
  }

  /**
   * Getter method for property dataList.
   *
   * @return property value of dataList
   */
  public List<T> getDataList() {
    return dataList;
  }

  /**
   * Getter method for property headerRow.
   *
   * @return property value of headerRow
   */
  public List<String> getHeaderRow() {
    return headerRow;
  }
}
